/**
 * 
 */
package com.cn.practice.singleton;

/**
 * 单例模式联系
 * 
 * @author zhangyang
 *
 */
public class SingletonPractice {

	public static void main(String[] args) {
		// 饿汉式-静态方法
		System.out.println(Ehan1.getInstance() == Ehan1.getInstance());
		// 饿汉式-静态代码块
		System.out.println(Ehan2.getInstance() == Ehan2.getInstance());
		// 懒汉式-非线程安全
		System.out.println(Lanhan1.getInstance() == Lanhan1.getInstance());
		// 懒汉式-线程安全
		System.out.println(Lanhan2.getInstance() == Lanhan2.getInstance());
		//双重检查
		System.out.println(DoubleCheck.getInstance() == DoubleCheck.getInstance());
		//静态内部类
		System.out.println(StaticInnerClass.getInstance() == StaticInnerClass.getInstance());
		//枚举
		System.out.println(EnumClass.getInstance() == EnumClass.getInstance());
	}
}

/**
 * 饿汉式-静态方法
 * 
 * @author zhangyang
 *
 */
class Ehan1 {
	// 私有化类构造器
	private Ehan1() {

	}

	// 此优化静态变量-返回值是这个类
	private static final Ehan1 instance = new Ehan1();

	public static Ehan1 getInstance() {
		return instance;
	}
}

/**
 * 饿汉式-静态代码块
 * 
 * @author zhangyang
 *
 */
class Ehan2 {
	// 私有化类构造器
	private Ehan2() {

	}

	// 静态变量
	private static Ehan2 instance;
	static {
		instance = new Ehan2();
	}

	public static Ehan2 getInstance() {
		return instance;
	}

}

/**
 * 懒汉式-非线程安全-实际不能用
 * 
 * @author zhangyang
 *
 */
class Lanhan1 {
	// 私有化类构造器
	private Lanhan1() {

	}

	// 静态变量
	private static Lanhan1 instance;

	public static Lanhan1 getInstance() {
		if (instance == null) {
			instance = new Lanhan1();
		}

		return instance;
	}
}

/**
 * 懒汉式-线程安全-几乎不能用，getInstance是单线程效率太差
 * 
 * @author zhangyang
 *
 */
class Lanhan2 {
	// 私有化类构造器
	private Lanhan2() {

	}

	// 静态变量
	private static Lanhan2 instance;

	public static synchronized Lanhan2 getInstance() {
		if (instance == null) {
			instance = new Lanhan2();
		}

		return instance;
	}
}

/**
 * 双重检查 -能用推荐 代码多
 * 
 * @author zhangyang
 *
 */
class DoubleCheck {
	// 私有化类构造器
	private DoubleCheck() {

	}

	// 静态变量-volatile关键字
	private static volatile DoubleCheck instance;

	// 检查两次instance == null 两次之间用synchronized关键字锁住
	public static DoubleCheck getInstance() {
		if (instance == null) {
			synchronized (DoubleCheck.class) {
				if (instance == null) {
					instance = new DoubleCheck();
				}
			}

		}
		return instance;
	}
}

/**
 * 静态内部类 -推荐代码少
 * 
 * @author zhangyang
 *
 */
class StaticInnerClass {
	// 私有化类构造器
	private StaticInnerClass() {

	}

	// 静态内部类
	private static class InnerClass {
		// 里面有一个变量返回上面的类
		private static StaticInnerClass instance = new StaticInnerClass();
	}

	// 共有的外部方法
	public static StaticInnerClass getInstance() {
		return InnerClass.instance;
	}
}

/**
 * 枚举 effective java作者都推荐这样写单例
 * @author zhangyang
 *
 */
 enum EnumClass{
	 instaance;
	 public static EnumClass getInstance(){
		 return instaance;
	 }
 }